;
; Copyright (c) Microsoft Corporation.  All rights reserved.
;
;
; Use of this sample source code is subject to the terms of the Microsoft
; license agreement under which you licensed this sample source code. If
; you did not accept the terms of the license agreement, you are not
; authorized to use this sample source code. For the terms of the license,
; please see the license agreement between you and Microsoft or, if applicable,
; see the LICENSE.RTF on your install media or the root of your tools installation.
; THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR INDEMNITIES.
;
;
; (C) Copyright 2006 Marvell International Ltd.
; All Rights Reserved
;
;******************************************************************************
;
;  COPYRIGHT (C) 2002 Intel Corporation.
;
;  This software as well as the software described in it is furnished under 
;  license and may only be used or copied in accordance with the terms of the 
;  license. The information in this file is furnished for informational use 
;  only, is subject to change without notice, and should not be construed as 
;  a commitment by Intel Corporation. Intel Corporation assumes no 
;  responsibility or liability for any errors or inaccuracies that may appear 
;  in this document or any software that may be provided in association with 
;  this document.
; 
;  Except as permitted by such license, no part of this document may be 
;  reproduced, stored in a retrieval system, or transmitted in any form or by 
;  any means without the express written consent of Intel Corporation. 
;
;  FILENAME:       xllp_intc.s
;
;  PURPOSE:        Provides low level INTC primitive functions written specifically 
;                  for the PXA/Zylonite processor/platform.  
;
;******************************************************************************


	INCLUDE xlli_monahans_defs.inc

;
; List of primitive functions in this module:
;
    EXPORT XllpIntcDisableInterrupts 
    EXPORT XllpIntcRestoreInts 
    EXPORT XllpReadINTCReg
    EXPORT XllpWriteINTCReg
 
    AREA    |.text|, CODE, READONLY, ALIGN=5        ; Align =5 required for "ALIGN 32" to work

 


;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; UINT32  XllpIntcDisableInts (void)
;;
;;  Disable IRQ and FIQ interrupts by setting the I+F bits in the CPSR.
;;  
;;  Returns (R0): the state of the I+F bits before they were set 
;;
;;  Assumes caller is running in privileged mode.
;;

XllpIntcDisableInterrupts   FUNCTION

    mov     r1, #(xlli_CPSR_I_Bit:OR:xlli_CPSR_F_Bit)
	mov		r3, r0
	
	mrs     r2, cpsr
	and     r0, r2, r1      ; This is the return with the current int flags
    orr     r2, r2, r1
    and		r2, r2, r3
    msr     cpsr_c, r2      ; Only interested in control fields

	IF :DEF: Interworking
      IF Interworking :LOR: Thumbing
        bx  lr
      ELSE
        mov  pc, lr         ; return
      ENDIF 
	ELSE
      mov  pc, lr           ; return
    ENDIF 

	ENDFUNC


;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; void  XllpIntcRestoreInts (UINT32)
;;
;;  Set the I+F bits in the CPSR to the values received in R0.
;;  - Protects against changing any other bits the CPSR.
;;  - If the value returned by pmDisableInts() is used as the parameter, 
;;    this function restores the interrupt enable/disable state to
;;    that which existed at the time pmDisableInts() was invoked.
;;
;;  Assumes caller is running in privileged mode.
;;

XllpIntcRestoreInts  FUNCTION

    mov     r1, #(xlli_CPSR_I_Bit:OR:xlli_CPSR_F_Bit)
    and     r0, r0, r1  ; Isolate the I+F bits
    mrs     r2, cpsr    ; Get existing settings
    bic     r2, r2, r1  ; Clear out the flag locations
    orr     r2, r2, r0  ; Set the restored flags in place
    msr     cpsr_c, r2  ; Only interested in control fields

	IF :DEF: Interworking
      IF Interworking :LOR: Thumbing
        bx  lr
      ELSE
        mov  pc, lr     ; return
      ENDIF 
	ELSE
      mov  pc, lr       ; return
    ENDIF 

	ENDFUNC

 
 ;
; XllpReadINTCReg - Read the INTC Register
;
; Description:
; 	This routine reads the designated INTC register via CoProcesser 6.
;
; Input Parameters:
;       r0 - arg1, INTC register number to read.  
;	if r0 contains:
;		0 ->XLLP_INTC_ICIP,	/*!< Interrupt Controller IRQ Pending register*/
;		1 ->XLLP_INTC_ICMR,	/*!< Interrupt Controller Mask register*/
;		2 ->XLLP_INTC_ICLR,	/*!< Interrupt Controller level register*/
;		3 ->XLLP_INTC_ICFP,	/*!< Interrupt Controller FIQ Pending register*/
;		4 ->XLLP_INTC_ICPR,	/*!< Interrupt Controller Pendingregister*/
;		5 ->XLLP_INTC_ICHP,	/*!< Interrupt Controller Highest Priority register*/
;		6 ->XLLP_INTC_ICIP2,/*!< Interrupt Controller IRQ Pending register*/
;		7 ->XLLP_INTC_ICMR2,/*!< Interrupt Controller Mask register*/
;		8 ->XLLP_INTC_ICLR2,/*!< Interrupt Controller level register*/
;		9 ->XLLP_INTC_ICFP2,/*!< Interrupt Controller FIQ Pending register*/
;		10->XLLP_INTC_ICPR2	/*!< Interrupt Controller Pendingregister*/
; Returns:	
;	r0 - 32-bit value read from CoProcessor
;    
; Registers Modified:
;	CoProcessor Register Modified: None
;	General Purpose Registers Modified: r0	
;
; NOTE:  
;	Error checking not included
;

XllpReadINTCReg	FUNCTION

    cmp     r0, #10
    addls	pc, pc, r0, lsl #2
    b		RdICIP
    b		RdICMR
    b		RdICLR
    b		RdICFP
    b		RdICPR
    b		RdICHP
    b		RdICIP2
    b		RdICMR2
    b		RdICLR2
    b		RdICFP2
	b		RdICPR2
			
RdICIP  
    mrc     p6, 0, r0, c0, c0, 0		; Read PMNC
    b       RRet
RdICMR  
    mrc     p6, 0, r0, c1, c0, 0		; Read CCNT
    b		RRet
RdICLR  
    mrc     p6, 0, r0, c2, c0, 0		; Read PMN0
    b		RRet
RdICFP  
    mrc     p6, 0, r0, c3, c0, 0		; Read PMN1
    b		RRet
RdICPR  
    mrc     p6, 0, r0, c4, c0, 0		; Read PMN2
    b		RRet
RdICHP  
    mrc     p6, 0, r0, c5, c0, 0		; Read PMN3
    b		RRet
RdICIP2  
    mrc     p6, 0, r0, c6, c0, 0		; Read INTEN
    b		RRet
RdICMR2  
    mrc     p6, 0, r0, c7, c0, 0		; Read FLAG
    b		RRet
RdICLR2
    mrc     p6, 0, r0, c8, c0, 0		; Read FLAG
    b		RRet 
RdICFP2  
    mrc     p6, 0, r0, c9, c0, 0		; Read EVTSEL
    b		RRet
RdICPR2
	mrc     p6, 0, r0, c10, c0, 0		; Read EVTSEL
    b		RRet
    
RRet
	IF :DEF: Interworking
      IF Interworking :LOR: Thumbing
        bx  lr
      ELSE
        mov  pc, lr          ; return
      ENDIF 
	ELSE
      mov  pc, lr          ; return
    ENDIF 
	 
    ENDFUNC

;
; XllpWriteINTCReg - Writes to the INTC Register
;
; Description:
; 	This routine writes to the designated INTC register via CoProcesser 6.
;
; Input Parameters:   
;       r0 - arg1 - INTC register number to write
;       r1 - arg2 - Value to write to INTC register
;
;	if r0 contains:
;	if r0 contains:
;		0 ->XLLP_INTC_ICIP,	/*!< Interrupt Controller IRQ Pending register*/
;		1 ->XLLP_INTC_ICMR,	/*!< Interrupt Controller Mask register*/
;		2 ->XLLP_INTC_ICLR,	/*!< Interrupt Controller level register*/
;		3 ->XLLP_INTC_ICFP,	/*!< Interrupt Controller FIQ Pending register*/
;		4 ->XLLP_INTC_ICPR,	/*!< Interrupt Controller Pendingregister*/
;		5 ->XLLP_INTC_ICHP,	/*!< Interrupt Controller Highest Priority register*/
;		6 ->XLLP_INTC_ICIP2,/*!< Interrupt Controller IRQ Pending register*/
;		7 ->XLLP_INTC_ICMR2,/*!< Interrupt Controller Mask register*/
;		8 ->XLLP_INTC_ICLR2,/*!< Interrupt Controller level register*/
;		9 ->XLLP_INTC_ICFP2,/*!< Interrupt Controller FIQ Pending register*/
;		10->XLLP_INTC_ICPR2	/*!< Interrupt Controller Pendingregister*/
;
; Returns:
;	None
;
; Registers Modified:
;	CoProcessor Register Modified: INTC Register
;	General Purpose Registers Modified: None
;
; NOTE   
;	Error checking not included
;

XllpWriteINTCReg  FUNCTION

    cmp     r0, #10
    addls	pc, pc, r0, lsl #2
    b		WrICIP
    b		WrICMR
    b		WrICLR
    b		WrICFP
    b		WrICPR
    b		WrICHP
    b		WrICIP2
    b		WrICMR2
    b		WrICLR2
    b		WrICFP2
	b		WrICPR2
			
WrICIP  
    mcr     p6, 0, r0, c0, c0, 0		; Read PMNC
    b       WRet
WrICMR  
    mcr     p6, 0, r0, c1, c0, 0		; Read CCNT
    b		WRet
WrICLR  
    mcr     p6, 0, r0, c2, c0, 0		; Read PMN0
    b		WRet
WrICFP  
    mcr     p6, 0, r0, c3, c0, 0		; Read PMN1
    b		WRet
WrICPR  
    mcr     p6, 0, r0, c4, c0, 0		; Read PMN2
    b		WRet
WrICHP  
    mcr     p6, 0, r0, c5, c0, 0		; Read PMN3
    b		WRet
WrICIP2  
    mcr     p6, 0, r0, c6, c0, 0		; Read INTEN
    b		WRet
WrICMR2  
    mcr     p6, 0, r0, c7, c0, 0		; Read FLAG
    b		WRet
WrICLR2
    mcr     p6, 0, r0, c8, c0, 0		; Read FLAG
    b		WRet 
WrICFP2  
    mcr     p6, 0, r0, c9, c0, 0		; Read EVTSEL
    b		WRet
WrICPR2
	mcr     p6, 0, r0, c10, c0, 0		; Read EVTSEL
    b		WRet
    
WRet
	IF :DEF: Interworking
      IF Interworking :LOR: Thumbing
        bx  lr
      ELSE
        mov  pc, lr          ; return
      ENDIF 
	ELSE
      mov  pc, lr          ; return
    ENDIF 
	 
    ENDFUNC

	END